package com.ruoyi.wms.service.impl;

import java.util.List;
import java.math.BigDecimal;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.util.Random;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.exception.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.wms.mapper.WmsInventoryMapper;
import com.ruoyi.wms.domain.WmsInventory;
import com.ruoyi.wms.domain.WmsInventoryLog;
import com.ruoyi.wms.domain.dto.InventoryIncreaseRequest;
import com.ruoyi.wms.domain.dto.InventoryIncreaseResponse;
import com.ruoyi.wms.domain.dto.InventoryDecreaseRequest;
import com.ruoyi.wms.domain.dto.InventoryDecreaseResponse;
import java.util.ArrayList;
import com.ruoyi.wms.service.IWmsInventoryService;
import com.ruoyi.wms.service.IWmsInventoryLogService;
import com.ruoyi.wms.service.IWmsLocationService;
import com.ruoyi.wms.service.IWmsCargoOwnerService;
import com.ruoyi.wms.service.IWmsWarehouseService;
import com.ruoyi.wms.service.IWmsItemService;
import com.ruoyi.wms.service.IWmsSupplierService;
import com.ruoyi.wms.domain.WmsLocation;
import com.ruoyi.system.service.ISysTenantService;

/**
 * 库存信息Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-01-01
 */
@Service
public class WmsInventoryServiceImpl implements IWmsInventoryService 
{
    @Autowired
    private WmsInventoryMapper wmsInventoryMapper;

    @Autowired
    private IWmsInventoryLogService inventoryLogService;

    @Autowired
    private IWmsLocationService wmsLocationService;

    @Autowired
    private IWmsCargoOwnerService wmsCargoOwnerService;

    @Autowired
    private IWmsWarehouseService wmsWarehouseService;

    @Autowired
    private IWmsItemService wmsItemService;

    @Autowired
    private IWmsSupplierService wmsSupplierService;

    @Autowired
    private ISysTenantService sysTenantService;

    /**
     * 查询库存信息
     * 
     * @param inventoryId 库存信息主键
     * @return 库存信息
     */
    @Override
    public WmsInventory selectWmsInventoryById(Long inventoryId)
    {
        return wmsInventoryMapper.selectWmsInventoryById(inventoryId);
    }

    /**
     * 查询库存信息列表
     * 
     * @param wmsInventory 库存信息
     * @return 库存信息
     */
    @Override
    public List<WmsInventory> selectWmsInventoryList(WmsInventory wmsInventory)
    {
        // 设置租户ID
        wmsInventory.setTenantId(SecurityUtils.getTenantId());
        return wmsInventoryMapper.selectWmsInventoryList(wmsInventory);
    }

    /**
     * 新增库存信息
     * 
     * @param wmsInventory 库存信息
     * @return 结果
     */
    @Override
    public int insertWmsInventory(WmsInventory wmsInventory)
    {
        // 设置租户ID和创建信息
        wmsInventory.setTenantId(SecurityUtils.getTenantId());
        wmsInventory.setCreateBy(SecurityUtils.getUsername());
        wmsInventory.setCreateTime(DateUtils.getNowDate());
        return wmsInventoryMapper.insertWmsInventory(wmsInventory);
    }

    /**
     * 修改库存信息
     * 
     * @param wmsInventory 库存信息
     * @return 结果
     */
    @Override
    public int updateWmsInventory(WmsInventory wmsInventory)
    {
        wmsInventory.setUpdateBy(SecurityUtils.getUsername());
        wmsInventory.setUpdateTime(DateUtils.getNowDate());
        return wmsInventoryMapper.updateWmsInventory(wmsInventory);
    }

    /**
     * 批量删除库存信息
     * 
     * @param inventoryIds 需要删除的库存信息主键
     * @return 结果
     */
    @Override
    public int deleteWmsInventoryByIds(Long[] inventoryIds)
    {
        return wmsInventoryMapper.deleteWmsInventoryByIds(inventoryIds);
    }

    /**
     * 删除库存信息信息
     * 
     * @param inventoryId 库存信息主键
     * @return 结果
     */
    @Override
    public int deleteWmsInventoryById(Long inventoryId)
    {
        return wmsInventoryMapper.deleteWmsInventoryById(inventoryId);
    }

    /**
     * 入库操作
     * 
     * @param wmsInventory 库存信息
     * @param qty 入库数量
     * @param documentNo 单据号
     * @param operator 操作人
     * @return 结果
     */
    @Override
    @Transactional
    public int inbound(WmsInventory wmsInventory, BigDecimal qty, String documentNo, String operator)
    {
        // 查找是否存在相同条件的库存记录
        WmsInventory existingInventory = wmsInventoryMapper.selectWmsInventoryByCondition(wmsInventory);
        
        int result = 0;
        BigDecimal beforeQty = BigDecimal.ZERO;
        BigDecimal afterQty = qty;
        
        if (existingInventory != null)
        {
            // 更新现有库存
            beforeQty = existingInventory.getTotalQty();
            afterQty = beforeQty.add(qty);
            
            result = wmsInventoryMapper.increaseInventoryQty(existingInventory.getInventoryId(), qty, operator);
            wmsInventory.setInventoryId(existingInventory.getInventoryId());
        }
        else
        {
            // 创建新库存记录
            wmsInventory.setAvailableQty(qty);
            wmsInventory.setFrozenQty(BigDecimal.ZERO);
            wmsInventory.setTotalQty(qty);
            wmsInventory.setStatus("NORMAL"); // 设置默认状态为正常
            
            // 安全获取租户ID
            Long tenantId = SecurityUtils.getTenantIdSafe();
            if (tenantId == null) {
                throw new RuntimeException("无法获取当前用户的租户ID，请确保用户已正确登录并分配租户");
            }
            wmsInventory.setTenantId(tenantId);
            
            // 分配库位：查找仓库下的临时库位（类型为1）
            if (wmsInventory.getWarehouseId() != null) {
                List<WmsLocation> tempLocations = wmsLocationService.selectWmsLocationByWarehouseIdAndType(
                    wmsInventory.getWarehouseId(), 1); // 1-临时库位
                
                if (tempLocations != null && !tempLocations.isEmpty()) {
                    // 如果有多个临时库位，随机选择一个
                    WmsLocation selectedLocation;
                    if (tempLocations.size() == 1) {
                        selectedLocation = tempLocations.get(0);
                    } else {
                        Random random = new Random();
                        selectedLocation = tempLocations.get(random.nextInt(tempLocations.size()));
                    }
                    wmsInventory.setLocationId(selectedLocation.getId());
                } else {
                    throw new RuntimeException("请维护一个临时库位");
                }
            }
            
            wmsInventory.setCreateBy(operator);
            wmsInventory.setCreateTime(DateUtils.getNowDate());
            
            result = wmsInventoryMapper.insertWmsInventory(wmsInventory);
        }
        
        // 记录操作日志
        if (result > 0)
        {
            recordOperationLog("INBOUND", documentNo, wmsInventory, qty, beforeQty, afterQty, operator);
        }
        
        return result;
    }

    /**
     * 出库操作
     * 
     * @param inventoryId 库存ID
     * @param qty 出库数量
     * @param documentNo 单据号
     * @param operator 操作人
     * @return 结果
     */
    @Override
    @Transactional
    public int outbound(Long inventoryId, BigDecimal qty, String documentNo, String operator)
    {
        WmsInventory inventory = wmsInventoryMapper.selectWmsInventoryById(inventoryId);
        if (inventory == null || inventory.getAvailableQty().compareTo(qty) < 0)
        {
            return 0; // 库存不足
        }
        
        BigDecimal beforeQty = inventory.getTotalQty();
        BigDecimal afterQty = beforeQty.subtract(qty);
        
        int result = wmsInventoryMapper.decreaseInventoryQty(inventoryId, qty, operator);
        
        // 记录操作日志
        if (result > 0)
        {
            recordOperationLog("OUTBOUND", documentNo, inventory, qty, beforeQty, afterQty, operator);
        }
        
        return result;
    }

    /**
     * 冻结库存
     * 
     * @param inventoryId 库存ID
     * @param qty 冻结数量
     * @param documentNo 单据号
     * @param operator 操作人
     * @return 结果
     */
    @Override
    @Transactional
    public int freezeInventory(Long inventoryId, BigDecimal qty, String documentNo, String operator)
    {
        WmsInventory inventory = wmsInventoryMapper.selectWmsInventoryById(inventoryId);
        if (inventory == null || inventory.getAvailableQty().compareTo(qty) < 0)
        {
            return 0; // 可用库存不足
        }
        
        BigDecimal beforeQty = inventory.getFrozenQty();
        BigDecimal afterQty = beforeQty.add(qty);
        
        int result = wmsInventoryMapper.freezeInventoryQty(inventoryId, qty, operator);
        
        // 记录操作日志
        if (result > 0)
        {
            recordOperationLog("FREEZE", documentNo, inventory, qty, beforeQty, afterQty, operator);
        }
        
        return result;
    }

    /**
     * 解冻库存
     * 
     * @param inventoryId 库存ID
     * @param qty 解冻数量
     * @param documentNo 单据号
     * @param operator 操作人
     * @return 结果
     */
    @Override
    @Transactional
    public int unfreezeInventory(Long inventoryId, BigDecimal qty, String documentNo, String operator)
    {
        WmsInventory inventory = wmsInventoryMapper.selectWmsInventoryById(inventoryId);
        if (inventory == null || inventory.getFrozenQty().compareTo(qty) < 0)
        {
            return 0; // 冻结库存不足
        }
        
        BigDecimal beforeQty = inventory.getFrozenQty();
        BigDecimal afterQty = beforeQty.subtract(qty);
        
        int result = wmsInventoryMapper.unfreezeInventoryQty(inventoryId, qty, operator);
        
        // 记录操作日志
        if (result > 0)
        {
            recordOperationLog("UNFREEZE", documentNo, inventory, qty, beforeQty, afterQty, operator);
        }
        
        return result;
    }

    /**
     * 根据条件查询库存记录
     * 
     * @param wmsInventory 库存查询条件
     * @return 库存信息
     */
    @Override
    public WmsInventory selectWmsInventoryByCondition(WmsInventory wmsInventory)
    {
        wmsInventory.setTenantId(SecurityUtils.getTenantId());
        return wmsInventoryMapper.selectWmsInventoryByCondition(wmsInventory);
    }

    /**
     * 增加商品库存
     * 
     * @param request 增加库存请求
     * @return 增加库存响应
     */
    @Override
    @Transactional
    public InventoryIncreaseResponse increaseInventory(InventoryIncreaseRequest request)
    {
        // 1. 参数验证
        validateIncreaseRequest(request);
        
        // 2. 验证关联数据存在性
        validateRelatedData(request);
        
        // 3. 查找现有库存记录
        WmsInventory queryCondition = buildQueryCondition(request);
        WmsInventory existingInventory = wmsInventoryMapper.selectWmsInventoryByCondition(queryCondition);
        
        BigDecimal beforeQty = BigDecimal.ZERO;
        BigDecimal afterQty = request.getIncreaseQty();
        Long inventoryId;
        WmsInventory finalInventory = null;
        Date operationTime = DateUtils.getNowDate();
        
        if (existingInventory != null)
        {
            // 4a. 更新现有库存
            beforeQty = existingInventory.getAvailableQty();
            afterQty = beforeQty.add(request.getIncreaseQty());
            inventoryId = existingInventory.getInventoryId();
            finalInventory = existingInventory;
            
            // 更新库存数量
            int updateResult = wmsInventoryMapper.increaseInventoryQty(inventoryId, request.getIncreaseQty(), SecurityUtils.getUsername());
            if (updateResult <= 0) {
                throw new ServiceException("更新库存失败");
            }
        }
        else
        {
            // 4b. 创建新库存记录
            WmsInventory newInventory = buildNewInventory(request);
            int insertResult = wmsInventoryMapper.insertWmsInventory(newInventory);
            if (insertResult <= 0) {
                throw new ServiceException("创建库存记录失败");
            }
            inventoryId = newInventory.getInventoryId();
            finalInventory = newInventory;
        }
        
        // 5. 记录操作日志
        Long logId = recordIncreaseOperationLog(request, existingInventory, finalInventory, beforeQty, afterQty, operationTime);
        
        // 6. 构建响应
        return new InventoryIncreaseResponse(
            inventoryId,
            beforeQty,
            request.getIncreaseQty(),
            afterQty,
            operationTime,
            logId
        );
    }
    
    /**
     * 验证增加库存请求参数
     */
    private void validateIncreaseRequest(InventoryIncreaseRequest request)
    {
        // 验证日期格式和逻辑
        if (request.getProductionDate() != null && request.getExpirationDate() != null)
        {
            if (request.getProductionDate().after(request.getExpirationDate()))
            {
                throw new ServiceException("生产日期不能晚于过期日期");
            }
        }
        
        if (request.getProductionDate() != null)
        {
            Date today = new Date();
            if (request.getProductionDate().after(today))
            {
                throw new ServiceException("生产日期不能晚于当前日期");
            }
        }
        
        // 验证数量精度
        if (request.getIncreaseQty().scale() > 3)
        {
            throw new ServiceException("增加数量最多支持3位小数");
        }
    }
    
    /**
     * 验证关联数据存在性
     */
    private void validateRelatedData(InventoryIncreaseRequest request)
    {
        // 验证租户存在性
        if (sysTenantService.selectTenantById(request.getTenantId()) == null)
        {
            throw new ServiceException("租户不存在");
        }
        
        // 验证货主存在性
        if (wmsCargoOwnerService.selectWmsCargoOwnerById(request.getOwnerId()) == null)
        {
            throw new ServiceException("货主不存在");
        }
        
        // 验证仓库存在性
        if (wmsWarehouseService.selectWmsWarehouseById(request.getWarehouseId()) == null)
        {
            throw new ServiceException("仓库不存在");
        }
        
        // 验证库位存在性（如果提供）
        if (request.getLocationId() != null && wmsLocationService.selectWmsLocationById(request.getLocationId()) == null)
        {
            throw new ServiceException("库位不存在");
        }
        
        // 验证商品存在性
        if (wmsItemService.selectWmsItemById(request.getItemId()) == null)
        {
            throw new ServiceException("商品不存在");
        }
        
        // 验证供应商存在性（如果提供）
        if (request.getSupplierId() != null && wmsSupplierService.selectWmsSupplierById(request.getSupplierId()) == null)
        {
            throw new ServiceException("供应商不存在");
        }
        
        // 验证库存状态字典值
        validateInventoryStatus(request.getInventoryStatus());
    }
    
    /**
     * 构建查询条件
     */
    private WmsInventory buildQueryCondition(InventoryIncreaseRequest request)
    {
        WmsInventory condition = new WmsInventory();
        condition.setTenantId(request.getTenantId());
        condition.setOwnerId(request.getOwnerId());
        condition.setWarehouseId(request.getWarehouseId());
        condition.setLocationId(request.getLocationId());
        condition.setItemId(request.getItemId());
        condition.setBatchNo(request.getBatchNo());
        condition.setContainerNo(request.getContainerNo());
        condition.setSupplierId(request.getSupplierId());
        condition.setStatus(request.getInventoryStatus());
        return condition;
    }
    
    /**
     * 构建新库存记录
     */
    private WmsInventory buildNewInventory(InventoryIncreaseRequest request)
    {
        WmsInventory inventory = new WmsInventory();
        inventory.setTenantId(request.getTenantId());
        inventory.setOwnerId(request.getOwnerId());
        inventory.setSupplierId(request.getSupplierId());
        inventory.setWarehouseId(request.getWarehouseId());
        inventory.setLocationId(request.getLocationId());
        inventory.setItemId(request.getItemId());
        inventory.setBatchNo(request.getBatchNo());
        inventory.setContainerNo(request.getContainerNo());
        inventory.setProductionDate(request.getProductionDate());
        inventory.setExpirationDate(request.getExpirationDate());
        inventory.setAvailableQty(request.getIncreaseQty());
        inventory.setFrozenQty(BigDecimal.ZERO);
        inventory.setTotalQty(request.getIncreaseQty());
        inventory.setUnit(request.getUnit());
        inventory.setStatus(request.getInventoryStatus());
        inventory.setCreateBy(SecurityUtils.getUsername());
        inventory.setCreateTime(DateUtils.getNowDate());
        
        // 如果没有指定库位，分配默认库位
        if (inventory.getLocationId() == null)
        {
            assignDefaultLocation(inventory);
        }
        
        return inventory;
    }
    
    /**
     * 分配默认库位
     */
    private void assignDefaultLocation(WmsInventory inventory)
    {
        List<WmsLocation> tempLocations = wmsLocationService.selectWmsLocationByWarehouseIdAndType(
            inventory.getWarehouseId(), 1); // 1-临时库位
        
        if (tempLocations != null && !tempLocations.isEmpty())
        {
            WmsLocation selectedLocation;
            if (tempLocations.size() == 1)
            {
                selectedLocation = tempLocations.get(0);
            }
            else
            {
                Random random = new Random();
                selectedLocation = tempLocations.get(random.nextInt(tempLocations.size()));
            }
            inventory.setLocationId(selectedLocation.getId());
        }
        else
        {
            throw new ServiceException("请维护一个临时库位");
        }
    }
    
    /**
     * 记录增加库存操作日志
     */
    private Long recordIncreaseOperationLog(InventoryIncreaseRequest request, WmsInventory existingInventory,
                                          WmsInventory finalInventory, BigDecimal beforeQty, BigDecimal afterQty, Date operationTime)
    {
        WmsInventoryLog log = new WmsInventoryLog();
        log.setTenantId(request.getTenantId());
        log.setOperationType(request.getOperationType());
        log.setOwnerId(request.getOwnerId());
        log.setWarehouseId(request.getWarehouseId());
        log.setItemId(request.getItemId());
        log.setSupplierId(request.getSupplierId());
        log.setOperationQty(request.getIncreaseQty());

        log.setBeforeQty(beforeQty);
        log.setAfterQty(afterQty);
        log.setOperationTime(operationTime);
        log.setOperationBy(SecurityUtils.getUsername());
        log.setDocumentType(request.getDocumentType());
        log.setDocumentNo(request.getDocumentNo());
        log.setReason(request.getReason());
        
        // 设置操作前字段
        if (existingInventory != null)
        {
            // 存在现有库存记录时，记录现有库存的信息
            log.setBeforeLocationId(existingInventory.getLocationId());
            log.setBeforeBatchNo(existingInventory.getBatchNo());
            log.setBeforeContainerNo(existingInventory.getContainerNo());
            log.setBeforeStatus(existingInventory.getStatus());
        }
        else
        {
            // 不存在现有库存记录时，操作前字段为空
            log.setBeforeLocationId(null);
            log.setBeforeBatchNo(null);
            log.setBeforeContainerNo(null);
            log.setBeforeStatus(null);
        }
        
        // 设置操作后字段
        // 根据API文档要求设置操作后字段
        
        // 1. 操作后库位ID：如果请求中指定了库位ID，则使用请求中指定的库位ID；
        //    如果请求中未指定库位ID且存在现有库存记录，则使用现有库存记录的库位ID
        Long afterLocationId = request.getLocationId();
        if (afterLocationId == null && existingInventory != null) {
            afterLocationId = existingInventory.getLocationId();
        }
        log.setAfterLocationId(afterLocationId);
        
        // 2. 操作后批次号：使用请求中的批次号（可为空）
        log.setAfterBatchNo(request.getBatchNo());
        
        // 3. 操作后容器号：使用请求中的容器号（可为空）
        log.setAfterContainerNo(request.getContainerNo());
        
        // 4. 操作后库存状态：使用请求中的库存状态（非空）
        log.setAfterStatus(request.getInventoryStatus());
        
        inventoryLogService.recordInventoryLog(log);
        return log.getLogId();
    }

    /**
     * 记录操作日志
     */
    private void recordOperationLog(String operationType, String documentNo, WmsInventory inventory, 
                                    BigDecimal operationQty, BigDecimal beforeQty, BigDecimal afterQty, 
                                    String operator)
    {
        WmsInventoryLog log = new WmsInventoryLog();
        log.setTenantId(inventory.getTenantId());
        log.setOperationType(operationType);
        log.setDocumentNo(documentNo);
        log.setOwnerId(inventory.getOwnerId());
        log.setWarehouseId(inventory.getWarehouseId());
        log.setBeforeLocationId(inventory.getLocationId());
        log.setItemId(inventory.getItemId());
        log.setBeforeBatchNo(inventory.getBatchNo());
        log.setBeforeContainerNo(inventory.getContainerNo());
        log.setOperationQty(operationQty);
        log.setBeforeQty(beforeQty);
        log.setAfterQty(afterQty);
        log.setOperationTime(DateUtils.getNowDate());
        log.setOperationBy(operator);

        
        inventoryLogService.recordInventoryLog(log);
    }
    
    /**
     * 验证库存状态字典值
     */
    private void validateInventoryStatus(String inventoryStatus)
    {
        // 定义有效的库存状态值（基于wms_inventory_status字典）
        String[] validStatuses = {"NORMAL", "ALLOCATED", "PICKED", "FROZEN", "DAMAGED", "EXPIRED"};
        
        boolean isValid = false;
        for (String validStatus : validStatuses)
        {
            if (validStatus.equals(inventoryStatus))
            {
                isValid = true;
                break;
            }
        }
        
        if (!isValid)
        {
            throw new ServiceException("库存状态值无效，必须是以下值之一：NORMAL（正常）、ALLOCATED（已分配）、PICKED（已拣货）、FROZEN（冻结）、DAMAGED（损坏）、EXPIRED（过期）");
        }
    }

    /**
     * 减少商品库存
     * 
     * @param request 减少库存请求
     * @return 减少库存响应
     */
    @Override
    @Transactional
    public InventoryDecreaseResponse decreaseInventory(InventoryDecreaseRequest request)
    {
        // 1. 参数验证
        validateDecreaseRequest(request);
        
        // 2. 验证关联数据存在性
        validateRelatedDataForDecrease(request);
        
        // 3. 查询库存总量
        BigDecimal totalQty = wmsInventoryMapper.selectInventoryTotalQty(
            request.getTenantId(), request.getOwnerId(), request.getWarehouseId(),
            request.getItemId(), request.getInventoryStatus(), request.getLocationId(),
            request.getSupplierId(), request.getBatchNo(), request.getContainerNo());
        
        // 4. 验证库存是否充足
        if (totalQty == null || totalQty.compareTo(request.getDecreaseQty()) < 0)
        {
            throw new ServiceException(String.format("库存不足，当前可用库存：%s，需要扣减：%s", 
                totalQty == null ? "0" : totalQty.toString(), request.getDecreaseQty().toString()));
        }
        
        // 5. 查询库存列表（按FIFO排序）
        List<WmsInventory> inventoryList = wmsInventoryMapper.selectInventoryListForDecrease(
            request.getTenantId(), request.getOwnerId(), request.getWarehouseId(),
            request.getItemId(), request.getInventoryStatus(), request.getLocationId(),
            request.getSupplierId(), request.getBatchNo(), request.getContainerNo());
        
        if (inventoryList == null || inventoryList.isEmpty())
        {
            throw new ServiceException("未找到可扣减的库存记录");
        }
        
        // 6. 按顺序逐条扣减库存
        Date operationTime = DateUtils.getNowDate();
        String operator = SecurityUtils.getUsername();
        BigDecimal remainingQty = request.getDecreaseQty();
        List<InventoryDecreaseResponse.DecreaseDetail> decreaseDetails = new ArrayList<>();
        List<Long> logIds = new ArrayList<>();
        
        for (WmsInventory inventory : inventoryList)
        {
            if (remainingQty.compareTo(BigDecimal.ZERO) <= 0)
            {
                break;
            }
            
            BigDecimal beforeQty = inventory.getAvailableQty();
            BigDecimal decreaseFromThis;
            BigDecimal afterQty;
            
            if (beforeQty.compareTo(remainingQty) >= 0)
            {
                // 当前库存够用
                decreaseFromThis = remainingQty;
                afterQty = beforeQty.subtract(remainingQty);
                remainingQty = BigDecimal.ZERO;
            }
            else
            {
                // 当前库存不够用，全部扣减
                decreaseFromThis = beforeQty;
                afterQty = BigDecimal.ZERO;
                remainingQty = remainingQty.subtract(beforeQty);
            }
            
            // 7. 逐条更新库存数量
            int updateResult = wmsInventoryMapper.decreaseInventoryQty(
                inventory.getInventoryId(), decreaseFromThis, operator);
            
            if (updateResult <= 0)
            {
                throw new ServiceException(String.format("库存扣减失败，库存ID：%d，扣减数量：%s", 
                    inventory.getInventoryId(), decreaseFromThis.toString()));
            }
            
            // 记录操作日志
            Long logId = recordDecreaseOperationLog(request, inventory, beforeQty, 
                decreaseFromThis, afterQty, operationTime);
            logIds.add(logId);
            
            // 记录扣减详情
            InventoryDecreaseResponse.DecreaseDetail detail = new InventoryDecreaseResponse.DecreaseDetail(
                inventory.getInventoryId(), inventory.getLocationId(), inventory.getBatchNo(),
                inventory.getContainerNo(), beforeQty, decreaseFromThis, afterQty, logId);
            decreaseDetails.add(detail);
        }
        
        // 8. 删除库存数量为0的记录
        wmsInventoryMapper.deleteZeroQtyInventory(
            request.getTenantId(), request.getOwnerId(), request.getWarehouseId(),
            request.getItemId(), request.getInventoryStatus(), request.getLocationId(),
            request.getSupplierId(), request.getBatchNo(), request.getContainerNo());
        
        // 9. 构建响应
        InventoryDecreaseResponse response = new InventoryDecreaseResponse();
        response.setBeforeTotalQty(totalQty);
        response.setDecreaseQty(request.getDecreaseQty());
        response.setAfterTotalQty(totalQty.subtract(request.getDecreaseQty()));
        response.setOperationTime(operationTime);
        response.setLogIds(logIds);
        response.setAffectedRecords(decreaseDetails.size());
        response.setDecreaseDetails(decreaseDetails);
        
        return response;
    }
    
    /**
     * 验证减少库存请求参数
     */
    private void validateDecreaseRequest(InventoryDecreaseRequest request)
    {
        if (request == null)
        {
            throw new ServiceException("减少库存请求不能为空");
        }
        
        if (request.getTenantId() == null)
        {
            throw new ServiceException("租户ID不能为空");
        }
        
        if (request.getOwnerId() == null)
        {
            throw new ServiceException("货主ID不能为空");
        }
        
        if (request.getWarehouseId() == null)
        {
            throw new ServiceException("仓库ID不能为空");
        }
        
        if (request.getItemId() == null)
        {
            throw new ServiceException("商品ID不能为空");
        }
        
        if (request.getDecreaseQty() == null || request.getDecreaseQty().compareTo(BigDecimal.ZERO) <= 0)
        {
            throw new ServiceException("减少数量必须大于0");
        }
        
        if (request.getInventoryStatus() == null || request.getInventoryStatus().trim().isEmpty())
        {
            throw new ServiceException("库存状态不能为空");
        }
        
        if (request.getOperationType() == null || request.getOperationType().trim().isEmpty())
        {
            throw new ServiceException("操作类型不能为空");
        }
        
        // 验证库存状态字典值
        validateInventoryStatus(request.getInventoryStatus());
    }
    
    /**
     * 验证关联数据存在性
     */
    private void validateRelatedDataForDecrease(InventoryDecreaseRequest request)
    {
        // 验证租户存在性
        if (sysTenantService.selectTenantById(request.getTenantId()) == null)
        {
            throw new ServiceException("租户不存在");
        }
        
        // 验证货主存在性
        if (wmsCargoOwnerService.selectWmsCargoOwnerById(request.getOwnerId()) == null)
        {
            throw new ServiceException("货主不存在");
        }
        
        // 验证仓库存在性
        if (wmsWarehouseService.selectWmsWarehouseById(request.getWarehouseId()) == null)
        {
            throw new ServiceException("仓库不存在");
        }
        
        // 验证商品存在性
        if (wmsItemService.selectWmsItemById(request.getItemId()) == null)
        {
            throw new ServiceException("商品不存在");
        }
        
        // 验证库位存在性（如果指定了库位ID）
        if (request.getLocationId() != null && 
            wmsLocationService.selectWmsLocationById(request.getLocationId()) == null)
        {
            throw new ServiceException("库位不存在");
        }
        
        // 验证供应商存在性（如果指定了供应商ID）
        if (request.getSupplierId() != null && 
            wmsSupplierService.selectWmsSupplierById(request.getSupplierId()) == null)
        {
            throw new ServiceException("供应商不存在");
        }
    }
    
    /**
     * 记录减少库存操作日志
     */
    private Long recordDecreaseOperationLog(InventoryDecreaseRequest request, WmsInventory inventory,
                                           BigDecimal beforeQty, BigDecimal decreaseQty, BigDecimal afterQty, Date operationTime)
    {
        WmsInventoryLog log = new WmsInventoryLog();
        log.setTenantId(request.getTenantId());
        log.setOwnerId(request.getOwnerId());
        log.setSupplierId(inventory.getSupplierId());
        log.setWarehouseId(request.getWarehouseId());
        log.setBeforeLocationId(inventory.getLocationId());
        log.setItemId(request.getItemId());
        log.setBeforeBatchNo(inventory.getBatchNo());
        log.setBeforeContainerNo(inventory.getContainerNo());
        log.setOperationType(request.getOperationType());
        log.setBeforeQty(beforeQty);
        log.setOperationQty(decreaseQty);
        log.setAfterQty(afterQty);
        log.setDocumentType(request.getDocumentType());
        log.setDocumentNo(request.getDocumentNo());
        log.setReason(request.getReason());
        log.setOperationTime(operationTime);
        log.setOperationBy(SecurityUtils.getUsername());
        log.setAfterLocationId(inventory.getLocationId());
        log.setAfterBatchNo(inventory.getBatchNo());
        log.setAfterContainerNo(inventory.getContainerNo());
        log.setBeforeStatus(inventory.getStatus());
        log.setAfterStatus(inventory.getStatus());
        log.setCreateBy(SecurityUtils.getUsername());
        log.setCreateTime(operationTime);
        log.setRemark(request.getRemark());
        
        inventoryLogService.recordInventoryLog(log);
        return log.getLogId();
    }
}